package net.pulseproject.commons.midi;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;

import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiDevice.Info;

import net.pulseproject.commons.midi.entity.Device;
import net.pulseproject.commons.midi.entity.DeviceState;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.inject.Inject;

public class DeviceLister {

	private static final Log LOG = LogFactory.getLog(DeviceLister.class);
	
	
	private final MidiDeviceCache deviceCache;
	
	private Collection<Device> cachedDevices;
	
	
	@Inject
	public DeviceLister(final MidiDeviceCache deviceCache) {
		LOG.debug("new DeviceLister(deviceCache)");
		this.deviceCache = deviceCache;
	}
	
	public final Collection<Device> listDevices() {
		LOG.info("listDevices()");
		
		if(this.cachedDevices == null) {
			this.loadCache();
		}
		
		assert (this.cachedDevices != null);
		return this.cachedDevices;
	}
	
	private void loadCache() {
		LOG.info("loadCache()");
		final Collection<MidiDevice> midiDevices = this.deviceCache.fetchMidiDevices();
		final Collection<Device> foundDevices = new HashSet<Device>(midiDevices.size());
		
		for (final MidiDevice midiDevice : midiDevices) {
			final Info info = midiDevice.getDeviceInfo();
			
			final String portName = info.getName();
			final int maxReceivers = midiDevice.getMaxReceivers();
			final int maxTransmitters = midiDevice.getMaxTransmitters();
			final DeviceState state = DeviceState.byMaxReceiversTransmitters(maxReceivers, maxTransmitters);
			
			final Device device = new Device(portName, maxReceivers, maxTransmitters, state);
			
			foundDevices.add(device);
		}
		
		this.cachedDevices = Collections.unmodifiableCollection(foundDevices);
	}
	
}
